#include "Control.h"
Control::Control()
	:Component(COMP_CONTROL),
	m_input(),
	m_escape(),
	m_cameraUp(),
	m_cameraDown(),
	m_cameraLeft(),
	m_cameraRight(),
	m_cameraRoundLeft(),
	m_cameraRoundRight(),
	m_cameraIn(),
	m_cameraOut()
{
}

Control::~Control()
{
}

void Control::AddedToObject()
{
	RequestComponent(COMP_CONFIG,&Control::Initial);
	RequestComponent(COMP_INPUT,&Control::SetInputImpl);
}

void Control::Initial(const Message& msg)
{
	CompPtr config;
	AuxUnGroupArgus(msg.p,config);
	m_keyMap=boost::dynamic_pointer_cast<Config>(config)->GetKeyControl();
}

void Control::InitialDefaultKey()
{
	BindKeyToFunction("KEY_W",m_cameraUp);
	BindKeyToFunction("KEY_S",m_cameraDown);
	BindKeyToFunction("KEY_A",m_cameraLeft);
	BindKeyToFunction("KEY_D",m_cameraRight);
	BindKeyToFunction("KEY_Q",m_cameraRoundLeft);
	BindKeyToFunction("KEY_E",m_cameraRoundRight);
	BindKeyToFunction("KEY_R",m_cameraIn);
	BindKeyToFunction("KEY_F",m_cameraOut);
	BindKeyToFunction("ESC",m_escape);
}

void Control::BindKeyToFunction(const string& key,KeyBoardFunc& f)
{
	if(!m_input)
		EXCEPTION("Variable m_input is empty!")
	if(key=="KEY_A")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_A);
	else if(key=="KEY_B")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_B);
	else if(key=="KEY_C")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_C);
	else if(key=="KEY_D")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_D);
	else if(key=="KEY_E")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_E);
	else if(key=="KEY_F")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_F);
	else if(key=="KEY_G")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_G);
	else if(key=="KEY_H")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_H);
	else if(key=="KEY_I")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_I);
	else if(key=="KEY_J")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_J);
	else if(key=="KEY_K")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_K);
	else if(key=="KEY_L")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_L);
	else if(key=="KEY_M")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_M);
	else if(key=="KEY_N")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_N);
	else if(key=="KEY_O")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_O);
	else if(key=="KEY_P")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_P);
	else if(key=="KEY_Q")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_Q);
	else if(key=="KEY_R")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_R);
	else if(key=="KEY_S")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_S);
	else if(key=="KEY_T")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_T);
	else if(key=="KEY_U")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_U);
	else if(key=="KEY_V")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_V);
	else if(key=="KEY_W")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_W);
	else if(key=="KEY_X")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_X);
	else if(key=="KEY_Y")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_Y);
	else if(key=="KEY_Z")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_Z);
	else if(key=="ESC")
		f=boost::bind(&InputClass::IsPressedKey,m_input.get(),DIK_ESCAPE);
}

void Control::InitialKeyFunction(const string& name, const string& key)
{
	if(name=="[CAMERA_UP]")
		BindKeyToFunction(key,m_cameraUp);
	else if(name=="[CAMERA_DOWN]")
		BindKeyToFunction(key,m_cameraDown);
	else if(name=="[CAMERA_LEFT]")
		BindKeyToFunction(key,m_cameraLeft);
	else if(name=="[CAMERA_RIGHT]")
		BindKeyToFunction(key,m_cameraRight);
	else if(name=="[CAMERA_ROUND_LEFT]")
		BindKeyToFunction(key,m_cameraRoundLeft);
	else if(name=="[CAMERA_ROUND_RIGHT]")
		BindKeyToFunction(key,m_cameraRoundRight);
	else if(name=="[CAMERA_IN]")
		BindKeyToFunction(key,m_cameraIn);
	else if(name=="[CAMERA_OUT]")
		BindKeyToFunction(key,m_cameraOut);
}

bool Control::Frame()
{
	try
	{
		if(!m_input)
			EXCEPTION("Variable m_input is empty!")
			
		m_input->Frame();
	
		if(m_cameraUp())
		{
			SendMessage(MSG_CAMERA_UP);
		}
	
		if(m_cameraDown())
		{
			SendMessage(MSG_CAMERA_DOWN);
		}
	
		if(m_cameraLeft())
		{
			SendMessage(MSG_CAMERA_LEFT);
		}
	
		if(m_cameraRight())
		{
			SendMessage(MSG_CAMERA_RIGHT);
		}
	
		if(m_cameraRoundLeft())
		{
			SendMessage(MSG_CAMERA_RLEFT);
		}
		
		if(m_cameraRoundRight())
		{
			SendMessage(MSG_CAMERA_RRIGHT);
		}
	
		if(m_cameraIn())
		{
			SendMessage(MSG_CAMERA_IN);
		}
	
		if(m_cameraOut())
		{
			SendMessage(MSG_CAMERA_OUT);
		}
		
		if(m_escape())
		{
			return false;
		}
	}
	catch(boost::bad_any_cast& e)
	{
		PRINT_BOOST_ERROR(e)
	}
	catch(std::exception& e)
	{
		PRINT_ERROR(e)
	}
	return true;
}

void Control::SetInputImpl(const Message& msg)
{
	CompPtr tmp;
	AuxUnGroupArgus(msg.p,tmp);
	m_input=boost::dynamic_pointer_cast<InputClass>(tmp);
	InitialDefaultKey();
	for(KeyMap::iterator iter=m_keyMap.begin();iter!=m_keyMap.end();iter++)
	{
		InitialKeyFunction(iter->first,iter->second);
	}	 
}